// compress.js
Page({
  data: {
    imageUrl: '',
    compressedImageUrl: '',
    quality: 60, // 更合理的默认质量
    formatIndex: 0, // 默认JPEG格式，压缩效果最好
    formats: ['JPEG', 'PNG', 'WebP'],
    originalSize: '',
    compressedSize: '',
    compressionRatio: '',
    compressing: false,
    canvasWidth: 300,
    canvasHeight: 300
  },

  onLoad() {
    console.log('压缩页面加载');
  },

  chooseImage() {
    wx.chooseMedia({
      count: 1,
      mediaType: ['image'],
      sourceType: ['album', 'camera'],
      success: (res) => {
        const tempFilePath = res.tempFiles[0].tempFilePath;
        const fileSize = res.tempFiles[0].size;
        
        this.setData({
          imageUrl: tempFilePath,
          originalSize: this.formatFileSize(fileSize),
          compressedImageUrl: '',
          compressedSize: '',
          compressionRatio: ''
        });
      },
      fail: (err) => {
        console.error('选择图片失败:', err);
        wx.showToast({
          title: '选择图片失败',
          icon: 'error'
        });
      }
    });
  },

  onQualityChange(e) {
    this.setData({
      quality: e.detail.value
    });
  },

  onFormatChange(e) {
    this.setData({
      formatIndex: e.detail.value
    });
  },

  compressImage() {
    if (!this.data.imageUrl) {
      wx.showToast({
        title: '请先选择图片',
        icon: 'error'
      });
      return;
    }

    this.setData({ compressing: true });

    // 获取原始文件信息
    wx.getFileInfo({
      filePath: this.data.imageUrl,
      success: (fileRes) => {
        const originalSizeBytes = fileRes.size;
        
        // 获取图片信息
        wx.getImageInfo({
          src: this.data.imageUrl,
          success: (res) => {
            const { width, height } = res;
            
            // 执行新版压缩逻辑
            this.compressImageNew(width, height, originalSizeBytes);
          },
          fail: (err) => {
            console.error('获取图片信息失败:', err);
            this.setData({ compressing: false });
            wx.showToast({
              title: '获取图片信息失败',
              icon: 'error'
            });
          }
        });
      },
      fail: (err) => {
        console.error('获取文件信息失败:', err);
        this.setData({ compressing: false });
        wx.showToast({
          title: '获取文件信息失败',
          icon: 'error'
        });
      }
    });
  },
  
  // 简单判断是否可能是PNG源文件
  isLikelyPngSource() {
    // 这里可以根据文件路径或其他信息判断
    // 简化处理，返回false
    return false;
  },
  
  // 强力压缩 - 使用更激进的设置
  forceCompress() {
    if (!this.data.imageUrl) {
      wx.showToast({
        title: '请先选择图片',
        icon: 'error'
      });
      return;
    }
    
    // 临时保存当前设置
    const originalQuality = this.data.quality;
    const originalFormat = this.data.formatIndex;
    
    // 设置强力压缩参数
    this.setData({
      quality: 25, // 更低质量
      formatIndex: 0 // 强制JPEG格式
    });
    
    wx.showModal({
      title: '强力压缩',
      content: '将使用25%质量和JPEG格式进行强力压缩，图片质量会明显下降但文件会很小。确定继续吗？',
      success: (res) => {
        if (res.confirm) {
          this.compressImage();
        } else {
          // 恢复原设置
          this.setData({
            quality: originalQuality,
            formatIndex: originalFormat
          });
        }
      }
    });
  },

  // 新版压缩方法 - 使用新Canvas API和更好的压缩策略
  compressImageNew(originalWidth, originalHeight, originalSizeBytes) {
    const query = wx.createSelectorQuery();
    query.select('#compressCanvas')
      .fields({ node: true, size: true })
      .exec((res) => {
        if (!res[0] || !res[0].node) {
          console.error('Canvas节点获取失败');
          this.fallbackToLegacyCompress(originalWidth, originalHeight, originalSizeBytes);
          return;
        }
        
        const canvas = res[0].node;
        const ctx = canvas.getContext('2d');
        
        // 计算最优压缩参数
        const compressParams = this.calculateOptimalCompression(originalWidth, originalHeight, originalSizeBytes);
        
        // 设置canvas尺寸
        canvas.width = compressParams.width;
        canvas.height = compressParams.height;
        
        // 创建图片对象
        const img = canvas.createImage();
        img.onload = () => {
          // 清空画布
          ctx.clearRect(0, 0, canvas.width, canvas.height);
          
          // 设置图片平滑处理
          ctx.imageSmoothingEnabled = true;
          ctx.imageSmoothingQuality = 'high';
          
          // 绘制图片
          ctx.drawImage(img, 0, 0, compressParams.width, compressParams.height);
          
          // 导出压缩图片
          wx.canvasToTempFilePath({
            canvas: canvas,
            quality: compressParams.quality,
            fileType: compressParams.format,
            success: (canvasRes) => {
              this.handleCompressResult(canvasRes.tempFilePath, originalSizeBytes);
            },
            fail: (err) => {
              console.error('Canvas导出失败:', err);
              this.fallbackToLegacyCompress(originalWidth, originalHeight, originalSizeBytes);
            }
          });
        };
        
        img.onerror = () => {
          console.error('图片加载失败');
          this.fallbackToLegacyCompress(originalWidth, originalHeight, originalSizeBytes);
        };
        
        img.src = this.data.imageUrl;
      });
  },
  
  // 计算最优压缩参数
  calculateOptimalCompression(width, height, sizeBytes) {
    const currentFormat = this.data.formats[this.data.formatIndex].toLowerCase();
    let quality = this.data.quality / 100;
    
    // 智能尺寸压缩
    let newWidth = width;
    let newHeight = height;
    
    // 根据文件大小和尺寸智能调整
    const megapixels = (width * height) / 1000000;
    const sizeMB = sizeBytes / (1024 * 1024);
    
    // 大图片需要更激进的压缩
    if (megapixels > 8 || sizeMB > 5) {
      const maxSize = 1500;
      if (width > maxSize || height > maxSize) {
        const ratio = Math.min(maxSize / width, maxSize / height);
        newWidth = Math.floor(width * ratio);
        newHeight = Math.floor(height * ratio);
      }
    } else if (megapixels > 4 || sizeMB > 2) {
      const maxSize = 1200;
      if (width > maxSize || height > maxSize) {
        const ratio = Math.min(maxSize / width, maxSize / height);
        newWidth = Math.floor(width * ratio);
        newHeight = Math.floor(height * ratio);
      }
    }
    
    // 格式优化
    let outputFormat = currentFormat;
    
    // 如果是PNG且用户选择JPEG，强制转换
    if (currentFormat === 'jpeg') {
      outputFormat = 'jpg'; // 微信小程序使用jpg而不是jpeg
    }
    
    // PNG格式的特殊处理
    if (outputFormat === 'png') {
      // PNG不支持质量参数，但可以通过尺寸压缩
      quality = 1.0;
      // 如果原图是PNG且很大，建议转为JPEG
      if (sizeMB > 1) {
        wx.showModal({
          title: '压缩建议',
          content: 'PNG格式文件较大，建议选择JPEG格式以获得更好的压缩效果',
          showCancel: false
        });
      }
    } else {
      // JPEG格式根据文件大小调整质量
      if (sizeMB > 3) {
        quality = Math.min(quality, 0.6); // 大文件限制最高质量
      } else if (sizeMB > 1) {
        quality = Math.min(quality, 0.8);
      }
    }
    
    return {
      width: newWidth,
      height: newHeight,
      quality: quality,
      format: outputFormat
    };
  },
  
  // 处理压缩结果
  handleCompressResult(compressedPath, originalSizeBytes) {
    wx.getFileInfo({
      filePath: compressedPath,
      success: (fileInfo) => {
        const compressedSize = fileInfo.size;
        
        // 如果压缩效果不佳，尝试更激进的压缩
        if (compressedSize >= originalSizeBytes * 0.9) {
          this.tryAggressiveCompress(compressedPath, originalSizeBytes);
          return;
        }
        
        const ratio = ((originalSizeBytes - compressedSize) / originalSizeBytes * 100).toFixed(1);
        
        this.setData({
          compressedImageUrl: compressedPath,
          compressedSize: this.formatFileSize(compressedSize),
          compressionRatio: `${ratio}%`,
          compressing: false
        });
        
        wx.showToast({
          title: `压缩完成，减少${ratio}%`,
          icon: 'success'
        });
      },
      fail: () => {
        this.setData({ compressing: false });
        wx.showToast({
          title: '获取文件信息失败',
          icon: 'error'
        });
      }
    });
  },
  
  // 尝试更激进的压缩
  tryAggressiveCompress(currentPath, originalSizeBytes) {
    wx.showModal({
      title: '压缩效果不佳',
      content: '当前设置压缩效果有限，是否尝试更激进的压缩？\n（将降低质量到40%并转为JPEG格式）',
      confirmText: '激进压缩',
      cancelText: '使用当前结果',
      success: (res) => {
        if (res.confirm) {
          // 保存原设置
          const originalQuality = this.data.quality;
          const originalFormat = this.data.formatIndex;
          
          // 设置激进参数
          this.setData({
            quality: 40,
            formatIndex: 0 // JPEG
          });
          
          // 重新压缩
          wx.getImageInfo({
            src: this.data.imageUrl,
            success: (res) => {
              this.compressImageNew(res.width, res.height, originalSizeBytes);
            },
            fail: () => {
              // 恢复设置
              this.setData({
                quality: originalQuality,
                formatIndex: originalFormat
              });
              this.useCurrentResult(currentPath, originalSizeBytes);
            }
          });
        } else {
          this.useCurrentResult(currentPath, originalSizeBytes);
        }
      }
    });
  },
  
  // 使用当前压缩结果
  useCurrentResult(compressedPath, originalSizeBytes) {
    wx.getFileInfo({
      filePath: compressedPath,
      success: (fileInfo) => {
        const compressedSize = fileInfo.size;
        const ratio = ((originalSizeBytes - compressedSize) / originalSizeBytes * 100).toFixed(1);
        
        this.setData({
          compressedImageUrl: compressedPath,
          compressedSize: this.formatFileSize(compressedSize),
          compressionRatio: `${ratio}%`,
          compressing: false
        });
      },
      fail: () => {
        this.setData({ compressing: false });
      }
    });
  },
  
  // 降级到旧版压缩方法
  fallbackToLegacyCompress(width, height, originalSizeBytes) {
    console.log('降级到旧版Canvas API');
    
    const compressParams = this.calculateOptimalCompression(width, height, originalSizeBytes);
    
    // 设置canvas尺寸
    this.setData({
      canvasWidth: compressParams.width,
      canvasHeight: compressParams.height
    });
    
    setTimeout(() => {
      const canvas = wx.createCanvasContext('compressCanvas', this);
      
      canvas.drawImage(this.data.imageUrl, 0, 0, compressParams.width, compressParams.height);
      canvas.draw(false, () => {
        setTimeout(() => {
          wx.canvasToTempFilePath({
            canvasId: 'compressCanvas',
            width: compressParams.width,
            height: compressParams.height,
            quality: compressParams.quality,
            fileType: compressParams.format,
            success: (canvasRes) => {
              this.handleCompressResult(canvasRes.tempFilePath, originalSizeBytes);
            },
            fail: (err) => {
              console.error('旧版压缩也失败:', err);
              this.setData({ compressing: false });
              wx.showToast({
                title: '压缩失败',
                icon: 'error'
              });
            }
          });
        }, 100);
      });
    }, 50);
  },

  saveImage() {
    if (!this.data.compressedImageUrl) {
      wx.showToast({
        title: '没有可保存的图片',
        icon: 'error'
      });
      return;
    }

    wx.saveImageToPhotosAlbum({
      filePath: this.data.compressedImageUrl,
      success: () => {
        wx.showToast({
          title: '保存成功',
          icon: 'success'
        });
      },
      fail: (err) => {
        if (err.errMsg.includes('auth deny')) {
          wx.showModal({
            title: '提示',
            content: '需要授权访问相册才能保存图片',
            success: (res) => {
              if (res.confirm) {
                wx.openSetting();
              }
            }
          });
        } else {
          wx.showToast({
            title: '保存失败',
            icon: 'error'
          });
        }
      }
    });
  },

  resetImage() {
    this.setData({
      imageUrl: '',
      compressedImageUrl: '',
      originalSize: '',
      compressedSize: '',
      compressionRatio: ''
    });
  },

  formatFileSize(bytes) {
    if (bytes === 0) return '0 B';
    const k = 1024;
    const sizes = ['B', 'KB', 'MB', 'GB'];
    const i = Math.floor(Math.log(bytes) / Math.log(k));
    return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i];
  },

  getFileSizeFromString(sizeStr) {
    const match = sizeStr.match(/([\d.]+)\s*(\w+)/);
    if (!match) return 0;
    
    const value = parseFloat(match[1]);
    const unit = match[2].toUpperCase();
    const units = { 'B': 1, 'KB': 1024, 'MB': 1024 * 1024, 'GB': 1024 * 1024 * 1024 };
    
    return value * (units[unit] || 1);
  }
})